package cn.tedu.ivos.base.handler;

import cn.hutool.bloomfilter.BloomFilter;
import cn.tedu.ivos.base.exception.ServiceException;
import cn.tedu.ivos.base.handler.JsonResult;
import io.minio.MinioClient;
import io.minio.ObjectWriteArgs;
import io.minio.ObjectWriteResponse;
import io.minio.PutObjectArgs;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@Api(tags = "上传文件")
@Slf4j
@RestController
@RequestMapping("/v1/file")
public class UploadController {
    @Autowired
    private BloomFilter bloomFilter;

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.file.path}")
    private String minioFilePath;
    /*
     * 定义方法处理图片上传功能
     */
    @ApiOperation("上传文件")
    @ApiImplicitParam(name = "file",value = "图片文件",required = true)
    @PostMapping("upload")
    //MultipartFile用来接收上传图片文件的对象
    //注意:形参file必须与前端upload上传组件的name一致!
    public CompletableFuture<JsonResult> upload(@RequestPart("file") MultipartFile file) throws IOException {
        //基于CompletableFuture实现异步任务编排上传
        return CompletableFuture.supplyAsync(
                ()->processUpload(file))
                .thenApply((item)->JsonResult.ok(item));

    }
    public String processUpload(MultipartFile file){
            System.out.println("===processUpload.start====");
       try {
            String md5File = DigestUtils.md5DigestAsHex(file.getBytes());
            log.debug("上传文件:file={}", md5File);
            if (bloomFilter.contains(md5File))
                throw new IllegalArgumentException("文件已存在");
            //1.得到原始文件名
            String fileName = file.getOriginalFilename();
            //2.获取图片后缀名
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            //3.生成一个唯一不重复的随机字符串作为新的文件名
            fileName = UUID.randomUUID() + suffix;
            //4.指定一个路径用来存储上传的图片文件,注意:这个路径必须自己电脑上有!
            String dirPath = "d:/files";
            //5.为了提高检索性能,我们可以设置一个自定义的日期路径作为图片存储的文件夹
            //一般以年月日的格式存储,比如2024/07/15
            SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
            //6.将当前的实际日期转为上面的日期格式
            String datePath = sdf.format(new Date());
            //7.将上面的盘符路径与日期路径拼接成一个完整的图片存储文件夹路径
           // File dirFile = new File(dirPath + datePath);
            //8.如果文件夹不存在,则依据此路径创建多层文件夹
//            if (!dirFile.exists()) {
//                dirFile.mkdirs();
//            }
            //9.拼接一个完整的图片文件路径
            String filePath = datePath + fileName;
            System.out.println("UploadController.filePath=" + filePath);
            //10.将图片保存在指定的文件夹中

           ObjectWriteResponse res = minioClient.putObject(PutObjectArgs.builder()
                   .bucket("public")
                   .object(filePath)
                   .contentType(file.getContentType())
                   .stream(file.getInputStream(), file.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build());
            //file.transferTo(new File(filePath));
            bloomFilter.add(md5File);
            //11.把日期路径+图片名 响应给前端,前端拿到这个数据后再回显图片
            System.out.println("===processUpload.end====");
            //return "http://192.168.8.100:9000/public"+filePath;
           return filePath;
        }catch (Exception e){
            e.printStackTrace();
            return "文件上传失败"+e.getMessage();
        }
    }
    @ApiOperation("删除文件")
    @ApiImplicitParam(name = "imgUrl",value = "图片路径",required = true)
    @PostMapping("remove")
    public JsonResult remove(String imgUrl){
        log.debug("图片删除:imgUrl={}",imgUrl);
        //拼接完整的路径,创建对应的java对象删除磁盘上对应的图片文件
        new File("d:/files"+imgUrl).delete();
        return JsonResult.ok();
    }
}